﻿using Roton.Memory;
using Roton.ZZT;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Roton.Wrapper
{
    /// <summary>
    /// Adapts IWorld to a Segment object.
    /// </summary>
    class WorldWrapper : IWorld
    {
        protected WorldWrapperProperties properties;
        protected Segment segment;

        public WorldWrapper(int offset, Segment segment, WorldWrapperProperties properties)
        {
            this.segment = segment;
            properties.OffsetAmmo += offset;
            properties.OffsetBoard += offset;
            properties.OffsetEnergyCycles += offset;
            properties.OffsetFlags += offset;
            properties.OffsetGems += offset;
            properties.OffsetHealth += offset;
            properties.OffsetKeys += offset;
            properties.OffsetLocked += offset;
            properties.OffsetScore += offset;
            properties.OffsetStones += offset;
            properties.OffsetTimePassed += offset;
            properties.OffsetTorchCycles += offset;
            properties.OffsetTorches += offset;
            this.properties = properties;
        }

        public int Ammo
        {
            get
            {
                return segment.Read16(properties.OffsetAmmo);
            }
            set
            {
                segment.Write16(properties.OffsetAmmo, value);
            }
        }

        public int Board
        {
            get
            {
                return segment.Read16(properties.OffsetBoard);
            }
            set
            {
                segment.Write16(properties.OffsetBoard, value);
            }
        }

        public int EnergyCycles
        {
            get
            {
                return segment.Read16(properties.OffsetEnergyCycles);
            }
            set
            {
                segment.Write16(properties.OffsetEnergyCycles, value);
            }
        }

        public IStringArray Flags
        {
            get { return new StringArrayWrapper(properties.OffsetFlags, properties.LengthFlags, segment); }
        }

        public int Gems
        {
            get
            {
                return segment.Read16(properties.OffsetGems);
            }
            set
            {
                segment.Write16(properties.OffsetGems, value);
            }
        }

        public int Health
        {
            get
            {
                return segment.Read16(properties.OffsetHealth);
            }
            set
            {
                segment.Write16(properties.OffsetHealth, value);
            }
        }

        public IBooleanArray Keys
        {
            get { return new BooleanArrayWrapper(properties.OffsetKeys, segment); }
        }

        public bool Locked
        {
            get
            {
                return segment.ReadBoolean(properties.OffsetLocked);
            }
            set
            {
                segment.WriteBoolean(properties.OffsetLocked, value);
            }
        }

        public IString Name
        {
            get
            {
                return Flags[0];
            }
        }

        public int Score
        {
            get
            {
                return segment.Read16(properties.OffsetScore);
            }
            set
            {
                segment.Write16(properties.OffsetScore, value);
            }
        }

        public int Stones
        {
            get
            {
                return segment.Read16(properties.OffsetStones);
            }
            set
            {
                segment.Write16(properties.OffsetStones, value);
            }
        }

        public int TimePassed
        {
            get
            {
                return segment.Read16(properties.OffsetTimePassed);
            }
            set
            {
                segment.Write16(properties.OffsetTimePassed, value);
            }
        }

        public int Torches
        {
            get
            {
                return segment.Read16(properties.OffsetTorches);
            }
            set
            {
                segment.Write16(properties.OffsetTorches, value);
            }
        }

        public int TorchCycles
        {
            get
            {
                return segment.Read16(properties.OffsetTorchCycles);
            }
            set
            {
                segment.Write16(properties.OffsetTorchCycles, value);
            }
        }
    }

    struct WorldWrapperProperties
    {
        public int LengthFlags;
        public int OffsetAmmo;
        public int OffsetBoard;
        public int OffsetEnergyCycles;
        public int OffsetFlags;
        public int OffsetGems;
        public int OffsetHealth;
        public int OffsetKeys;
        public int OffsetLocked;
        public int OffsetScore;
        public int OffsetStones;
        public int OffsetTimePassed;
        public int OffsetTorches;
        public int OffsetTorchCycles;
    }
}
